/*
 * Copyright (C) 2004 Derek James and Philip Tucker This file is part of ANJI
 * (Another NEAT Java Implementation). ANJI is free software; you can
 * redistribute it and/or modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version. This program is distributed
 * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received
 * a copy of the GNU General Public License along with this program; if not,
 * write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA created by Philip Tucker
 */
package com.anji.dilemma;

import org.apache.log4j.Logger;

import com.anji.tournament.Game;
import com.anji.tournament.GameConfiguration;
import com.anji.tournament.GameResults;
import com.anji.tournament.Player;
import com.anji.tournament.ScoringWeights;
import com.anji.util.Configurable;

/**
 * @author Philip Tucker
 */
public class Trial implements Game, Configurable {

  private static final Logger LOGGER = Logger.getLogger(Trial.class);

  private GameConfiguration gameConfig = GameConfiguration.DEFAULT;

  private String name = "DilemmaTrial";

  public GameResults play(Player contestant, Player opponent) {
    GameResults results = new GameResults();

    // players
    DilemmaPlayer playerOne = (DilemmaPlayer) contestant;
    DilemmaPlayer playerTwo = (DilemmaPlayer) opponent;
    if (gameConfig.doResetPlayers()) {
      playerOne.reset();
      playerTwo.reset();
    }

    Choice playerOneChoice = playerOne.choose(playerTwo.getPreviousChoice());
    if (playerOneChoice == null) {
      throw new IllegalStateException("null player1 choice");
    }
    Choice playerTwoChoice = playerTwo.choose(playerOne.getPreviousChoice());
    if (playerTwoChoice == null) {
      throw new IllegalStateException("null player2 choice");
    }

    switch (playerOneChoice) {
      case DEFECT:
        switch (playerTwoChoice) {
          case DEFECT:
            LOGGER.debug(playerOne.getPlayerId() + " and "
                + playerTwo.getPlayerId() + " both defect");
            results.incrementRawScore(1, 1);
            results.incrementTies(1);
            break;
          case COOPERATE:
            LOGGER.debug(playerOne.getPlayerId() + " rats out "
                + playerTwo.getPlayerId());
            results.incrementRawScore(5, 0);
            results.incrementPlayer1Wins(1);
            break;
        }
        break;
      case COOPERATE:
        switch (playerTwoChoice) {
          case DEFECT:
            LOGGER.debug(playerTwo.getPlayerId() + " rats out "
                + playerOne.getPlayerId());
            results.incrementRawScore(0, 5);
            results.incrementPlayer1Losses(1);
            break;
          case COOPERATE:
            LOGGER.debug(playerOne.getPlayerId() + " and "
                + playerTwo.getPlayerId() + " both cooperate");
            results.incrementRawScore(3, 3);
            results.incrementTies(1);
            break;
        }
        break;
    }
    return results;
  }

  /**
   * @see com.anji.tournament.Game#requiredPlayerClass()
   */
  public Class requiredPlayerClass() {
    return DilemmaPlayer.class;
  }

  /**
   * @see com.anji.tournament.Game#getMaxScore(com.anji.tournament.ScoringWeights)
   */
  public double getMaxScore(ScoringWeights aWeights) {
    return aWeights.getRawScoreValue() * 5;
  }

  /**
   * @see com.anji.tournament.Game#getMinScore(com.anji.tournament.ScoringWeights)
   */
  public double getMinScore(ScoringWeights aWeights) {
    return 0.0;
  }

  /**
   * @see com.anji.util.Configurable#init(com.anji.util.Properties)
   */
  public void init(com.anji.util.Properties props) throws Exception {
    gameConfig =
        (GameConfiguration) props
            .singletonObjectProperty(GameConfiguration.class);
    name += (" " + props.getName());
  }

}
